<template>
	<view class="contact page-pagination" :class="size=='large'?'size-large':size=='small'?'size-small':''">
		<view class="page-con">
			<view class="page-scroll">
				<view class="page-scroll-child">
					<!-- 首页 -->
					<view class="pag-btn start" :style="{color}" :class="[nowPage==1?'btn-ban':'',btnText?'btn-text':'']" v-if="showAround && !numAround" @click="clickStart">
						<text v-if="btnText">首页</text>
						<text v-else class="icon icon-left1"></text>
					</view>
					<!-- 上页 -->
					<view class="pag-btn prev" :style="{color}" :class="[nowPage==1?'btn-ban':'',btnText?'btn-text':'']" @click="clickPrev">
						<text v-if="btnText">上页</text>
						<text v-else class="icon icon-left"></text>
					</view>
					<!-- 简单模式 -->
					<view v-if="mode=='simple'" class="page-num simple"><text :style="{color}" style="margin-right: 10rpx;">{{nowPage}}</text>/ {{pageNum}}</view>
					<!-- 复杂模式 -->
					<view class="page-num" v-else>
						<template v-if="pageNum <= showPageSize">
							<view v-for="page in pageNumArr" :key="page" class="pag-btn" :style="{color, backgroundColor:(page==nowPage?color:'')}" :class="page==nowPage?'active':''" @click="clickPage(page)">{{page}}</view>
						</template>
						<template v-else>
							<!-- 第一页页码 -->
							<view class="pag-btn" :style="{color, backgroundColor:(nowPage==1?color:'')}" v-if="numAround" :class="nowPage==1?'active':''" @click="clickPage(1)">1</view>
							<!-- 左侧省略号 -->
							<view class="pag-btn ellipsis-btn" :style="{color}" v-show="(forceEllipses && getFirstPage != 1) || (numAround && getFirstPage != 2)"><text class="icon icon-more"></text></view>
							<template v-for="(p, i) in showPageSize">
								<template v-if="i<showPageSize-2">
									<!-- 中间页码 -->
									<view :key="i" class="pag-btn"
										:style="{color, backgroundColor:((getFirstPage+i)==nowPage?color:'')}"
										:class="(getFirstPage+i)==nowPage?'active':''"
										@click="clickPage(getFirstPage+i)">
										{{getFirstPage+i}}
									</view>
								</template>
								<template v-else>
									<!-- 若显示省略号，则页码只显示 showPageSize-2 页 -->
									<view :key="i" v-show="!forceEllipses && !numAround" class="pag-btn"
										:style="{color, backgroundColor:((getFirstPage+i)==nowPage?color:'')}"
										:class="(getFirstPage+i)==nowPage?'active':''"
										@click="clickPage(getFirstPage+i)">
										{{getFirstPage+i}}
									</view>
								</template>
							</template>
							<!-- 右侧省略号 -->
							<view class="pag-btn ellipsis-btn" :style="{color}" v-show="(forceEllipses && getFirstPage<pageNum-(showPageSize-3)) || (numAround && getFirstPage < pageNum-(showPageSize-2))">
								<text class="icon icon-more"></text>
							</view>
							<!-- 最后一页页码 -->
							<view class="pag-btn" :style="{color, backgroundColor:(nowPage==pageNum?color:'')}" v-if="numAround" v-show="getFirstPage < pageNum-(showPageSize-3)" :class="nowPage==pageNum?'active':''" @click="clickPage(pageNum)">{{pageNum}}</view>
						</template>
					</view>
					<!-- 下页 -->
					<view class="pag-btn next" :style="{color}" :class="[pageNum<=nowPage?'btn-ban':'',btnText?'btn-text':'']" @click="clickNext">
						<text v-if="btnText">下页</text>
						<text v-else class="icon icon-right"></text>
					</view>
					<!-- 尾页 -->
					<view class="pag-btn end" :style="{color}" :class="[pageNum<=nowPage?'btn-ban':'',btnText?'btn-text':'']" v-if="showAround && !numAround" @click="clickEnd">
						<text v-if="btnText">尾页</text>
						<text v-else class="icon icon-right1"></text>
					</view>
				</view>
			</view>
		</view>
		<view class="page-info">
			<slot />
			<view class="page-info-con" v-if="showPageInfo">
				<view>共 {{total}} 条，</view>
				<view>每页 {{pageSize}} 条，</view>
				<view>当前页 {{nowPage}}/{{pageNum}}<text v-if="showGoPage">，</text></view>
			</view>
			<view class="page-go" v-if="showGoPage">前往第
				<template v-if="trigger=='blur'">
					<input class="page-input" type="text" v-model="inputPage" @blur="goPage" @input="onInput" />页
				</template>
				<template v-else>
					<input class="page-input" type="text" v-model="inputPage" @input="onInput" />页
					<text v-if="trigger=='click'" class="page-input-btn" @click="goPage">跳转</text>
				</template>
			</view>
		</view>
	</view>
</template>
<script>
	/**
	 * @property {Number} total 总条数，默认0
	 * @property {Number} pageSize 每页条数，默认10
	 * @property {Number} currentPage 当前页，默认1
	 * @property {Number} showPageSize 显示的页码个数，默认5
	 * @property {String} mode = [multi|simple] 显示模式，默认multi
	 *  @value multi 标准模式(默认)
	 *  @value simple 简单模式，只显示当前页/总页数
	 * @property {Boolean} forceEllipses = [true|false] 是否显示省略号，默认false
	 * @property {Boolean} btnText = [true|false] 上页、下页、首页和尾页按钮是否显示汉字，默认false
	 * @property {Boolean} showAround = [true|false] 是否显示首页和尾页，默认false
	 * @property {Boolean} numAround = [true|false] 是否用页码表示首尾页，默认false
	 * @property {String} size = [large|normal|small] 按钮大小，默认normal
	 *  @value large 大号按钮
	 *  @value normal 普通按钮(默认)
	 *  @value small 小型按钮
	 * @property {Boolean} showPageInfo = [true|false] 是否显示分页信息，如总页数等，默认false
	 * @property {Boolean} showGoPage = [true|false] 是否显示input输入框，默认false
	 * @property {String} trigger = [blur|click] 跳转页码触发方式，默认blur
	 *  @value blur 失去焦点时触发(默认)
	 *  @value click 点击跳转按钮触发
	 */
	export default {
		name: 'PagePagination',
		props: {
			//总条数
			total: {
				type: Number,
				default: 0
			},
			//每页条数
			pageSize: {
				type: Number,
				default: 10
			},
			//当前页
			currentPage: {
				type: Number,
				default: 1
			},
			//显示的页码个数
			showPageSize: {
				type: Number,
				default: 5
			},
			//显示模式
			mode: {
				type: String,
				default: "multi"
			},
			//是否显示省略号
			forceEllipses: {
				type: Boolean,
				default: false
			},
			//是否显示汉字
			btnText: {
				type: Boolean,
				default: false
			},
			//是否显示首页和尾页
			showAround: {
				type: Boolean,
				default: false
			},
			//是否用页码表示首尾页
			numAround: {
				type: Boolean,
				default: false
			},
			//按钮大小
			size: {
				type: String,
				default: "normal"
			},
			//页码颜色
			color: {
				type: String,
				default: "#1989FA"
			},
			//是否显示页面信息
			showPageInfo: {
				type: Boolean,
				default: false
			},
			//是否显示前往跳转页
			showGoPage: {
				type: Boolean,
				default: false
			},
			//跳转页码触发方式
			trigger: {
				type: String,
				default: "blur"
			}
		},
		data() {
			return {
				nowPage: this.currentPage, //当前页
				inputPage: this.currentPage //input输入框绑定值
			}
		},
		watch: {
			currentPage(val) {
				this.nowPage = val > this.pageNum ? this.pageNum : val;
				this.inputPage = val > this.pageNum ? this.pageNum : val;
				if (val == 1) {
					this.nowPage = 1;
					this.inputPage = 1;
				}
			}
		},
		computed: {
			//总页数
			pageNum() {
				return Math.ceil(this.total / this.pageSize)
			},
			pageNumArr() { //解决uni-app某些版本中，存在v-for中循环数字时从0开始
				var pageNumArr = [];
				for (let i = 0; i < this.pageNum; i++) {
					pageNumArr.push(i + 1);
				}
				return pageNumArr;
			},
			//计算显示的第一个页码
			getFirstPage() {
				let firstPage = 0;
				let a = Math.floor((this.showPageSize - 1) / 2);
				let b = Math.floor(this.showPageSize / 2) - 1;
				if (this.nowPage <= a) {
					if (!this.numAround) firstPage = 1;
					else firstPage = 2;
				} else if (this.nowPage >= this.pageNum - b) {
					if (this.forceEllipses || this.numAround) firstPage = this.pageNum - this.showPageSize + 3;
					else firstPage = this.pageNum - this.showPageSize + 1;
				} else {
					if (this.forceEllipses || this.numAround) firstPage = this.nowPage - a + 1;
					else firstPage = this.nowPage - a;
				}
				return firstPage;
			}
		},
		methods: {
			//选择页码
			clickPage(page) {
				if (this.nowPage != page) {
					this.nowPage = page;
					this.change(page, 'page');
				}
			},
			//点击上页
			clickPrev() {
				if (this.nowPage > 1) {
					let nowPage = this.nowPage - 1;
					this.nowPage = nowPage;
					this.change(nowPage, 'prev');
				}
			},
			//点击下页
			clickNext() {
				if (this.nowPage < this.pageNum) {
					let nowPage = this.nowPage + 1;
					this.nowPage = nowPage;
					this.change(nowPage, 'next');
				}
			},
			//点击首页
			clickStart() {
				if (this.nowPage != 1) {
					let nowPage = 1;
					this.nowPage = nowPage;
					this.change(nowPage, 'homePage');
				}
			},
			//点击尾页
			clickEnd() {
				if (this.nowPage != this.pageNum) {
					let nowPage = this.pageNum;
					this.nowPage = nowPage;
					this.change(nowPage, 'endPage');
				}
			},
			//页码改变时触发
			change(nowPage, type) {
				this.inputPage = nowPage;
				this.$emit('change', nowPage, type);
			},
			onInput(event) {
				let self = this;
				let val = parseInt(event.target.value.replace(/[^\d]/g, ''));
				setTimeout(function() {
					self.inputPage = val ? (val > self.pageNum ? self.pageNum : val) : '';
				}, 10)
			},
			goPage() {
				this.nowPage = parseInt(this.inputPage ? this.inputPage : '1');
				this.inputPage = parseInt(this.inputPage ? this.inputPage : '1');
				this.change(parseInt(this.inputPage), 'goPage');
			}
		}
	}
</script>

<style>
	@import 'icon/iconfont.css';

	.page-pagination {
		width: 100%;
	}

	.page-pagination .page-con {
		width: 100%;
		display: flex;
		justify-content: center;
	}

	.page-pagination .page-con .page-scroll {
		display: flex;
		overflow-x: auto;
		overflow-y: hidden;
		margin: 0 auto;
	}

	.page-pagination .page-con .page-scroll-child {
		display: flex;
		white-space: nowrap;
		height: 62rpx;
		line-height: 62rpx;
		flex-direction: row;
	}

	.page-pagination .page-con .page-scroll-child .pag-btn {
		background-color: #FFF;
		color: #1989FA;
		font-size: 24rpx;
		border: 1px solid #EBEEF5;
		border-left: none;
		padding: 0 22rpx;
	}

	.page-pagination .page-con .page-scroll-child .pag-btn.start,
	.page-pagination .page-con .page-scroll-child .pag-btn.prev,
	.page-pagination .page-con .page-scroll-child .pag-btn.next,
	.page-pagination .page-con .page-scroll-child .pag-btn.end {
		padding: 0 14rpx;
	}

	.page-pagination .page-con .page-scroll-child .ellipsis-btn {
		padding: 0 10rpx;
		color: #999999 !important;
	}

	.page-pagination .page-con .page-scroll-child .pag-btn:has(> .icon-more) {
		padding: 0 14rpx;
	}

	.page-pagination .page-con .page-scroll-child .pag-btn:first-child {
		border-left: 1px solid #EBEEF5;
	}

	.page-pagination .page-con .page-scroll-child .pag-btn.active {
		background-color: #1989FA;
		color: #FFFFFF !important;
	}

	.page-pagination .page-con .page-scroll-child .pag-btn.btn-ban {
		color: #C0C4CC !important;
		cursor: not-allowed;
	}

	.page-pagination .page-con .page-scroll-child .page-num {
		display: flex;
		flex-direction: row;
	}

	.page-pagination .page-con .page-scroll-child .page-num.simple {
		padding: 0 80rpx;
		line-height: 68rpx;
		color: #303133;
		font-size: 32rpx;
	}

	.page-pagination .page-con .page-scroll-child .icon-right,
	.page-pagination .page-con .page-scroll-child .icon-left {
		font-size: 26rpx;
	}

	.page-pagination .page-info {
		display: flex;
		justify-content: center;
		line-height: 56rpx;
		margin-top: 10rpx;
		color: #606266;
		font-size: 28rpx;
		text-align: center;
	}

	.page-pagination .page-info .page-info-con {
		display: flex;
		flex-direction: row;
		justify-content: center;
	}

	.page-pagination .page-info .page-go {
		position: relative;
		top: -2rpx;
		display: flex;
		justify-content: center;
		flex-direction: row;
	}

	.page-pagination .page-info .page-go .page-input {
		display: inline-block;
		width: 80rpx;
		height: 52rpx;
		line-height: 52rpx;
		border: 1px solid #dcdfe6;
		border-radius: 8rpx;
		background-color: #FFF;
		padding: 0px 10rpx;
		margin: 0 10rpx;
		font-size: 28rpx;
		overflow: inherit;
		box-sizing: border-box;
		vertical-align: middle;
	}

	.page-pagination .page-info .page-go .page-input-btn {
		height: 52rpx;
		line-height: 52rpx;
		padding: 4rpx 14rpx;
		border-width: 1px;
		border-style: solid;
		border-radius: 3px;
		border-color: #DCDFE6;
		color: #303133;
		margin-left: 10rpx;
		opacity: 0.8;
		background-color: #FFF;
	}

	// 大号按钮
	.page-pagination.size-large .page-con .page-scroll-child {
		height: 78rpx;
		line-height: 78rpx;
	}

	.page-pagination.size-large .page-con .page-scroll-child .pag-btn {
		padding: 0 30rpx;
		font-size: 30rpx;
	}

	.page-pagination.size-large .page-con .page-scroll-child .pag-btn.start,
	.page-pagination.size-large .page-con .page-scroll-child .pag-btn.prev,
	.page-pagination.size-large .page-con .page-scroll-child .pag-btn.next,
	.page-pagination.size-large .page-con .page-scroll-child .pag-btn.end,
	.page-pagination.size-large .page-con .page-scroll-child .ellipsis-btn {
		padding: 0 24rpx;
	}

	.page-pagination.size-large .page-con .page-scroll-child .pag-btn.btn-text {
		padding: 0 12rpx;
	}

	// 小型按钮
	.page-pagination.size-small .page-con .page-scroll-child {
		height: 52rpx;
		line-height: 52rpx;
	}

	.page-pagination.size-small .page-con .page-scroll-child .pag-btn {
		padding: 0 14rpx;
	}

	.page-pagination.size-small .page-con .page-scroll-child .pag-btn.start,
	.page-pagination.size-small .page-con .page-scroll-child .pag-btn.prev,
	.page-pagination.size-small .page-con .page-scroll-child .pag-btn.next,
	.page-pagination.size-small .page-con .page-scroll-child .pag-btn.end {
		padding: 0 10rpx;
	}

	.page-pagination.size-small .page-con .page-scroll-child .ellipsis-btn {
		padding: 0 10rpx;
	}

	//解决nvue页面下不能正常显示问题
	[nvue-dir-column] .page-pagination uni-label,
	[nvue-dir-column] .page-pagination uni-swiper-item,
	[nvue-dir-column] .page-pagination uni-view {
		flex-direction: initial;
	}
</style>
